﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace EasyTrader.Order
{
    using PriceSignalList = List<EasyTrader.Signal.PriceSignal>;
    using PriceOrderList = List<EasyTrader.Order.OrderInfo>;
    public class OrderTable : EasyTrader.DataSet.ETDataTable
    {
#region  Fixed Order Variables
        private double m_FixedSellOrderVal = 0.0;
        public double FixedSellOrderVal
        {
            get { return m_FixedSellOrderVal; }
            set { m_FixedSellOrderVal = value; }
        }
        private double m_FixedBuyOrderVal = 0.0;
        public double FixedBuyOrderVal
        {
            get { return m_FixedBuyOrderVal; }
            set { m_FixedBuyOrderVal = value; }
        }
        private bool m_FixedBuyOrderEnable = false;
        public bool FixedBuyOrderEnable
        {
            get { return m_FixedBuyOrderEnable; }
            set { m_FixedBuyOrderEnable = value; }
        }
        private bool m_FixedSellOrderEnable = false;
        public bool FixedSellOrderEnable
        {
            get { return m_FixedSellOrderEnable; }
            set { m_FixedSellOrderEnable = value; }
        }

        public void ClearFixedBuyOrder()
        {
            m_FixedBuyOrderEnable = false;
            m_FixedBuyOrderVal = 0.00;
        }

        public void CleareFixedSellOrder()
        {
            m_FixedSellOrderEnable = false;
            m_FixedSellOrderVal = 0.00;
        }
#endregion
        private PriceOrderList m_OrderList = new PriceOrderList();
        public PriceOrderList OrderList
        {
            get { return m_OrderList; }
            set { m_OrderList = value; }
        }

        public OrderInfo GetLastOrder()
        {
            int orderCount = m_OrderList.Count;
            if (orderCount == 0)
                return null;

            return m_OrderList[orderCount - 1];
        }

        public void MakeOrderList()
        {
            int rowCount = GetRowCount();
            if (rowCount == 0)
                return;
            // 목록을 만들기 전에 기존의 목록을 제거해 준다.
            m_OrderList.Clear();

            DataRow curRow = Rows[0];
            int curLiquidAmount = Convert.ToInt32(curRow["청산가능수량"]);
            int curOrder = Convert.ToInt32(curRow["주문구분"]);
            int curConcAmount = Convert.ToInt32(curRow["체결수량"]);
            string strRemainCode = curRow["잔고구분코드"].ToString();
            int remainCode = 0;
            if (strRemainCode != "")
            {
                remainCode = Convert.ToInt32(strRemainCode);
            }
            double curConPrice = Convert.ToDouble(curRow["체결가격"]);
            OrderInfo newOrder = new OrderInfo();
            newOrder.Order = curOrder;
            newOrder.Price = curConPrice;
            newOrder.Amount = curConcAmount;
            newOrder.RemainCode = remainCode;
            newOrder.LiquidAmount = curLiquidAmount;
            m_OrderList.Add(newOrder);

            for (int i = 1; i < rowCount; i++)
            {
                curRow = Rows[i];
                DataRow prevRow = Rows[i - 1];

                curLiquidAmount = Convert.ToInt32(curRow["청산가능수량"]);
                curOrder = Convert.ToInt32(curRow["주문구분"]);
                curConcAmount = Convert.ToInt32(curRow["체결수량"]);
                strRemainCode = curRow["잔고구분코드"].ToString();
                remainCode = 0;
                if (strRemainCode != "")
                {
                    remainCode = Convert.ToInt32(strRemainCode);
                }
                curConPrice = Convert.ToDouble(curRow["체결가격"]);
                double prePrice = Convert.ToDouble(prevRow["체결가격"]);
                int preOrder = Convert.ToInt32(prevRow["주문구분"]);
                int prevLiquidAmount = Convert.ToInt32(prevRow["청산가능수량"]);
                // 이전 청산가능수량이 0보다 클 때
                if (prevLiquidAmount > 0)
                {
                    // 현재 청산 가능 수량이 남아 있지 않은 상태
                    if (curLiquidAmount <= 0) // 이전 주문이 완전히 청산된 경우
                    {
                        // 현재 주문을 그대로 등록해 준다. - 이 주문은 청산 주문이다.
                        newOrder = new OrderInfo();
                        newOrder.Order = curOrder;
                        newOrder.Price = curConPrice;
                        newOrder.Amount = curConcAmount;
                        newOrder.RemainCode = remainCode;
                        newOrder.LiquidAmount = curLiquidAmount;
                        m_OrderList.Add(newOrder);
                    }
                    // 현재 청산 가능 수량이 남아 있는 상태
                    // 이 경우는 주문이 종결되지 않고 청산 가능 수량이 남아 있는 상태이기 때문에 
                    // 주문을 수정해 줘야 하는 경우이다.
                    else // 이전 주문이 완전히 청산되지 않았거나 새로운 주문이 더 많거나, 이전과 같은 주문이 들어 온 경우
                    {
                        // 이전 주문과 현재 주문이 같은 경우
                        if (curOrder == preOrder)
                        {
                            // 평균 단가를 구한다. 평균단가로 다시 주문을 등록해 준다.
                            // 평균단가는 현재 청산 가능한 주문 개수로 이전청산 가능개수로 실현할 수 있는 손익을 나누어서 얻는다.
                            // 이 때 현재 주문은 무시한다.
                            // 이 주문은 수정된 주문이다.
                            // 현재 가격에서 이전 가격을 빼준다.
                            double profit = (curConPrice - prePrice) * prevLiquidAmount;
                            // 평균 수익을 구한다.
                            double unitPrice = profit / Convert.ToDouble(curLiquidAmount);
                            // 현재 가격에서 평균 수익을 빼준다.
                            // 이것이 새로운 평균 단가가 된다.
                            double newAvePrice = curConPrice - unitPrice;
                            newOrder = new OrderInfo();
                            newOrder.Order = curOrder;
                            newOrder.Price = newAvePrice;
                            newOrder.Amount = curLiquidAmount;
                            newOrder.RemainCode = remainCode;
                            newOrder.LiquidAmount = curLiquidAmount;
                            m_OrderList.Add(newOrder);
                        }
                        else // 이전 주문과 현재 주문이 다른 경우
                        {
                            // 현재 체결 수량이 이전 청산 가능 수량보다 많을 때 - 이전 주문이 청산되고 새로운 주문이 남음
                            if (curConcAmount > prevLiquidAmount)
                            {
                                // 청산된 주문의 손익을 계산
                                // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                                // 남은 주문에 대하여 다시 주문을 등록해 준다.
                                // 현재 주문은 무시한다.
                                // 이 주문은 수정 주문이다.
                                newOrder = new OrderInfo();
                                newOrder.Order = curOrder;
                                newOrder.Price = curConPrice;
                                newOrder.Amount = curLiquidAmount;
                                newOrder.RemainCode = remainCode;
                                newOrder.LiquidAmount = curLiquidAmount;
                                m_OrderList.Add(newOrder);
                            }
                            else // 현재 체결 수량이 이전 청산 가능 수량보다 적을 때 - 이전 주문이 남음
                            {
                                // 청산된 주문의 손익을 계산
                                // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                                // 남은 주문에 대하여 다시 주문을 등록해 준다.
                                // 현재 주문은 무시한다.
                                // 이 주문은 수정주문이다.
                                newOrder = new OrderInfo();
                                newOrder.Order = preOrder;
                                newOrder.Price = prePrice;
                                newOrder.Amount = curLiquidAmount;
                                newOrder.RemainCode = remainCode;
                                newOrder.LiquidAmount = curLiquidAmount;
                                m_OrderList.Add(newOrder);
                            }
                        }
                    }
                }
                else // 이전 청산 가능 수량이 0일 때 - 청산이 될 때 까지 그대로 주문을 가져간다.
                {
                    // 그대로 새로운 주문을 등록해 준다. - 이 주문은 신규 주문이다.
                    newOrder = new OrderInfo();
                    newOrder.Order = curOrder;
                    newOrder.Price = curConPrice;
                    newOrder.Amount = curConcAmount;
                    newOrder.RemainCode = remainCode;
                    newOrder.LiquidAmount = curLiquidAmount;
                    m_OrderList.Add(newOrder);
                }
            }
        }

        public double CalcProfit(ref double a_FixedProfit, ref double a_FlowProfit, double a_CurVal)
        {
            m_TotalProfit = 0.0;
            m_CurProfit = 0.0;
            if (m_OrderList.Count == 0)
                return m_TotalProfit;
            double deltaY = 0;
            a_FixedProfit = 0;
            a_FlowProfit = 0;

            OrderInfo curInfo = m_OrderList[m_OrderList.Count - 1];
            int curLiquidAmount = curInfo.LiquidAmount;
            // 여기서 현재 주문에 대한 실현 가능 이익을 계산해 준다.
            if (m_OrderList.Count == 1)
            {
                double concludedVal = curInfo.Price;
                deltaY = Math.Abs(a_CurVal - concludedVal);
                int remainCode = curInfo.RemainCode;
                if (remainCode == GlobalVar.RemainBuy)
                {
                    if (a_CurVal > concludedVal)
                    {
                        a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                        a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                    }
                    else
                    {
                        a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                        a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                    }
                }
                else if (remainCode == GlobalVar.RemainSell)
                {
                    if (a_CurVal < concludedVal)
                    {
                        a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                        a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                    }
                    else
                    {
                        a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                        a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                    }
                }

                m_TotalProfit = a_FlowProfit;
                m_CurProfit = a_FlowProfit;
                return m_TotalProfit;
            }

            for (int i = 1; i < m_OrderList.Count; i++)
            {
                curInfo = m_OrderList[i];
                OrderInfo prevInfo = null;
                curLiquidAmount = curInfo.LiquidAmount;

                prevInfo = m_OrderList[i - 1];

                int prevLiquidAmount = prevInfo.LiquidAmount;
                int curOrder = curInfo.Order;
                int curConcAmount = curInfo.Amount;
                int preOrder = prevInfo.Order;
                // 이전 청산가능수량이 0보다 클 때
                if (prevLiquidAmount > 0)
                {
                    // 현재 청산 가능 수량이 남아 있지 않은 상태
                    if (curLiquidAmount <= 0) // 이전 주문이 완전히 청산된 경우
                    {
                        // 이익을 계산해줘야 함
                        deltaY = curInfo.Price - prevInfo.Price;
                        // 이전 주문 매수 일 때
                        if (prevInfo.Order == GlobalVar.OrderBuy)
                        {
                            a_FixedProfit += (deltaY * 50) * curInfo.Amount;
                            a_FixedProfit -= GlobalVar.Fare;
                        }
                        else if (prevInfo.Order == GlobalVar.OrderSell) // 이전 주문 매도일 때
                        {
                            a_FixedProfit += (-deltaY * 50) * curInfo.Amount;
                            a_FixedProfit -= GlobalVar.Fare;
                        }
                    }
                    // 현재 청산 가능 수량이 남아 있는 상태
                    else // 이전 주문이 완전히 청산되지 않았거나 새로운 주문이 더 많거나, 이전과 같은 주문이 들어 온 경우
                    {
                        // 이전 주문과 현재 주문이 같은 경우
                        if (curOrder == preOrder)
                        {
                            // 평균 단가를 구한다. 평균단가로 다시 주문을 등록해 준다.
                            // 계산은 하지 않는다.
                        }
                        else // 이전 주문과 현재 주문이 다른 경우
                        {
                            // 현재 체결 수량이 이전 청산 가능 수량보다 많을 때 - 이전 주문이 청산되고 새로운 주문이 남음
                            if (curConcAmount > prevLiquidAmount)
                            {
                                // 청산된 주문의 손익을 계산
                                // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                                // 남은 주문에 대하여 다시 주문을 등록해 준다.
                                // 이익을 계산해줘야 함
                                deltaY = curInfo.Price - prevInfo.Price;
                                // 이전 주문 매수 일 때
                                if (prevInfo.Order == GlobalVar.OrderBuy)
                                {
                                    a_FixedProfit += (deltaY * 50) * curInfo.Amount;
                                    a_FixedProfit -= GlobalVar.Fare;
                                }
                                else if (prevInfo.Order == GlobalVar.OrderSell) // 이전 주문 매도일 때
                                {
                                    a_FixedProfit += (-deltaY * 50) * curInfo.Amount;
                                    a_FixedProfit -= GlobalVar.Fare;
                                }
                            }
                            else // 현재 체결 수량이 이전 청산 가능 수량보다 적을 때 - 이전 주문이 남음
                            {
                                // 청산된 주문의 손익을 계산
                                // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                                // 남은 주문에 대하여 다시 주문을 등록해 준다.
                                // 이익을 계산해줘야 함
                                deltaY = curInfo.Price - prevInfo.Price;
                                // 이전 주문 매수 일 때
                                if (prevInfo.Order == GlobalVar.OrderBuy)
                                {
                                    a_FixedProfit += (deltaY * 50) * curInfo.Amount;
                                    a_FixedProfit -= GlobalVar.Fare;
                                }
                                else if (prevInfo.Order == GlobalVar.OrderSell) // 이전 주문 매도일 때
                                {
                                    a_FixedProfit += (-deltaY * 50) * curInfo.Amount;
                                    a_FixedProfit -= GlobalVar.Fare;
                                }
                            }
                        }

                        // 여기서 현재 주문에 대한 실현 가능 이익을 계산해 준다.
                        if (i == m_OrderList.Count - 1)
                        {
                            double concludedVal = curInfo.Price;
                            deltaY = Math.Abs(a_CurVal - concludedVal);
                            int remainCode = curInfo.RemainCode;
                            if (remainCode == GlobalVar.RemainBuy)
                            {
                                if (a_CurVal > concludedVal)
                                {
                                    a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                    a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                                }
                                else
                                {
                                    a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                    a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                                }
                            }
                            else if (remainCode == GlobalVar.RemainSell)
                            {
                                if (a_CurVal < concludedVal)
                                {
                                    a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                    a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                                }
                                else
                                {
                                    a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                    a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                                }
                            }
                        }
                    }
                }
                else // 이전 청산 가능 수량이 0일 때 - 청산이 될 때 까지 그대로 주문을 가져간다.
                {
                    if (i == m_OrderList.Count - 1)
                    {
                        double concludedVal = curInfo.Price;
                        deltaY = Math.Abs(a_CurVal - concludedVal);
                        int remainCode = curInfo.RemainCode;
                        if (remainCode == GlobalVar.RemainBuy)
                        {
                            if (a_CurVal > concludedVal)
                            {
                                a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                            else
                            {
                                a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                        }
                        else if (remainCode == GlobalVar.RemainSell)
                        {
                            if (a_CurVal < concludedVal)
                            {
                                a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                            else
                            {
                                a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                        }
                    }
                }
            }

            m_TotalProfit = a_FixedProfit + a_FlowProfit;
            m_CurProfit = a_FlowProfit;

            return m_TotalProfit;
        }
        private bool m_PendingOrder = false;
        public bool PendingOrder
        {
            get { return m_PendingOrder; }
            set { m_PendingOrder = value; }
        }

        private int m_PendingOrderBuySell = 0;
        public int PendingOrderBuySell
        {
            get { return m_PendingOrderBuySell; }
            set { m_PendingOrderBuySell = value; }
        }
        private double m_PendingOrderVal = 0.0;
        public double PendingOrderVal
        {
            get { return m_PendingOrderVal; }
            set { m_PendingOrderVal = value; }
        }

        private int m_PendingOrderAmount = 0;
        public int PendingOrderAmount
        {
            get { return m_PendingOrderAmount; }
            set { m_PendingOrderAmount = value; }
        }

        // 청산후 주문이 들어왔을 때 청산중인 주문번호
        // 이 주문이 청산된 후에 본 주문이 나간다.
        private string m_LiquidatingOrderNumber = "";
        public string LiquidatingOrderNumber
        {
            get { return m_LiquidatingOrderNumber; }
            set { m_LiquidatingOrderNumber = value; }
        }

        private double m_TotalProfit = 0;
        public double TotalProfit
        {
            get { return m_TotalProfit; }
            set { m_TotalProfit = value; }
        }

        private double m_CurProfit = 0;
        public double CurProfit
        {
            get { return m_CurProfit; }
            set { m_CurProfit = value; }
        }

        public void ClearSignalList()
        {
            m_PriceSignalList.Clear();
        }

        // 신호를 신호 목록에 더한다. 이 때 중복된 신호는 피한다.
        public void AddSignal(EasyTrader.Signal.PriceSignal a_Signal)
        {
            if (m_PriceSignalList == null)
                return;

            int signalCount = m_PriceSignalList.Count;
            if (signalCount == 0)
            {
                m_PriceSignalList.Add(a_Signal);
                return;
            }

            EasyTrader.Signal.PriceSignal prevSignal = m_PriceSignalList[signalCount - 1];
            if (prevSignal.Type != a_Signal.Type)
            {
                m_PriceSignalList.Add(a_Signal);
            }
        }

        private PriceSignalList m_PriceSignalList = new PriceSignalList();
        public PriceSignalList PriceSignalList
        {
            get { return m_PriceSignalList; }
            set { m_PriceSignalList = value; }
        }

        // 이 함수는 현재 주문에 대하여 평균 단가를 계산하여 그 가격 위치를 반환한다.
        private void CalcProfit(ref double a_FixedProfit, ref double a_FlowProfit, double a_CurVal, OrderTable a_Table, int a_RowIndex)
        {
            if (a_Table == null || a_RowIndex < 0)
                return;
            int rowCount = a_Table.GetRowCount();
            DataRow curRow = a_Table.Rows[a_RowIndex];
            DataRow prevRow = null;
            int curLiquidAmount = Convert.ToInt32(curRow["청산가능수량"]);
            
            prevRow = a_Table.Rows[a_RowIndex];

            int prevLiquidAmount = Convert.ToInt32(prevRow["청산가능수량"]);
            int curOrder = Convert.ToInt32(curRow["주문구분"]);
            int curConcAmount = Convert.ToInt32(curRow["체결수량"]);
            int preOrder = Convert.ToInt32(prevRow["주문구분"]);
            // 이전 청산가능수량이 0보다 클 때
            if (prevLiquidAmount > 0)
            {
                // 현재 청산 가능 수량이 남아 있지 않은 상태
                if (curLiquidAmount <= 0) // 이전 주문이 완전히 청산된 경우
                {
                    // 이익을 계산해줘야 함
                }
                // 현재 청산 가능 수량이 남아 있는 상태
                else // 이전 주문이 완전히 청산되지 않았거나 새로운 주문이 더 많거나, 이전과 같은 주문이 들어 온 경우
                {
                    // 이전 주문과 현재 주문이 같은 경우
                    if (curOrder == preOrder)
                    {
                        // 평균 단가를 구한다. 평균단가로 다시 주문을 등록해 준다.
                    }
                    else // 이전 주문과 현재 주문이 다른 경우
                    {
                        // 현재 체결 수량이 이전 청산 가능 수량보다 많을 때 - 이전 주문이 청산되고 새로운 주문이 남음
                        if (curConcAmount > prevLiquidAmount)
                        {
                            // 청산된 주문의 손익을 계산
                            // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                            // 남은 주문에 대하여 다시 주문을 등록해 준다.
                        }
                        else // 현재 체결 수량이 이전 청산 가능 수량보다 적을 때 - 이전 주문이 남음
                        {
                            // 청산된 주문의 손익을 계산
                            // 남은 주문의 손익은 청산이 일어날 때 까지 그대로 둔다.
                            // 남은 주문에 대하여 다시 주문을 등록해 준다.
                        }
                    }

                    // 여기서 현재 주문에 대한 실현 가능 이익을 계산해 준다.
                    if (a_RowIndex == rowCount - 1)
                    {
                        double concludedVal = Convert.ToDouble(curRow["체결가격"]);
                        double deltaY = Math.Abs(a_CurVal - concludedVal);
                        int remainCode = Convert.ToInt32(curRow["잔고구분코드"]);
                        if (remainCode == GlobalVar.RemainBuy)
                        {
                            if (a_CurVal > concludedVal)
                            {
                                a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                            else
                            {
                                a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                        }
                        else if (remainCode == GlobalVar.RemainSell)
                        {
                            if (a_CurVal < concludedVal)
                            {
                                a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                            else
                            {
                                a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                                a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                            }
                        }
                    }
                }
            }
            else // 이전 청산 가능 수량이 0일 때 - 청산이 될 때 까지 그대로 주문을 가져간다.
            {
                // 여기서 현재 주문에 대한 실현 가능 이익을 계산해 준다.
                if (a_RowIndex == rowCount - 1)
                {
                    double concludedVal = Convert.ToDouble(curRow["체결가격"]);
                    double deltaY = Math.Abs(a_CurVal - concludedVal);
                    int remainCode = Convert.ToInt32(curRow["잔고구분코드"]);
                    if (remainCode == GlobalVar.RemainBuy)
                    {
                        if (a_CurVal > concludedVal)
                        {
                            a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                            a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                        }
                        else
                        {
                            a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                            a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                        }
                    }
                    else if (remainCode == GlobalVar.RemainSell)
                    {
                        if (a_CurVal < concludedVal)
                        {
                            a_FlowProfit += (deltaY * 50) * curLiquidAmount;
                            a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                        }
                        else
                        {
                            a_FlowProfit += (-deltaY * 50) * curLiquidAmount;
                            a_FlowProfit -= GlobalVar.Fare * curLiquidAmount;
                        }
                    }
                }
            }
        }
        // 계좌번호는 테이블 이름으로 갖는다.
        public OrderTable(string a_Name)
            : base(a_Name)
        {
            Init();
        }

        // 여기서 행을 추가해 준다.
        public void Init()
        {
            // 22 개 칼럼
            AddColumn("명령"); // 정상(0), 수정(1), 취소(2)
            AddColumn("BarIndex");
            AddColumn("주문시각");
            AddColumn("종목코드");
            AddColumn("주문수량");
            AddColumn("주문가격");
            AddColumn("주문구분"); // 매수 / 매도
            AddColumn("매매구분"); // 지정가, 시장가, 조건부지정가, 최유리지정가
            AddColumn("매매조건"); // 없음, IOC, FOK
            AddColumn("계좌명");
            AddColumn("종목명");
            AddColumn("주문번호");
            AddColumn("원주문번호");
            AddColumn("종합계좌번호");
            AddColumn("거래명칭");
            AddColumn("체결수량");
            AddColumn("체결가격");
            AddColumn("체결시각");
            AddColumn("주문상태"); // 접수, 정정확인, 취소확인, 체결, 거부
            AddColumn("잔고구분코드"); // 0 : 잔고없음, 1 : 매도, 2 : 매수
            AddColumn("잔고"); // 매수 혹은 매도에 대한 잔고 개수
            AddColumn("청산가능수량"); // 청산 가능 수량
        }

        // 주문번호가 맞는 모든 열을 가지고 온다.
        public DataRow GetRowByOrderNumber(string a_OrderNum)
        {
            int rowCount = Rows.Count;
            if (rowCount == 0)
                return null;
            for (int i = 0; i < rowCount; i++)
            {
                DataRow curRow = Rows[i];
                object orderNum = curRow["주문번호"];
                if (a_OrderNum.CompareTo(orderNum.ToString()) == 0)
                    return curRow;
            }

            return null;
        }

        // 1 : 매도, 2 : 매수, 매도 상태는 일때는 매수로 설정, 매수상태일 때는 매도로 설정
        private int m_StopOrderType = 0;
        public int StopOrderType
        {
            get { return m_StopOrderType; }
            set { m_StopOrderType = value; }
        }

        private double m_StopVal = 0;
        public double StopVal
        {
            get { return m_StopVal; }
            set { m_StopVal = value; }
        }

        private bool m_StopEnabled = false;
        public bool StopEnabled
        {
            get { return m_StopEnabled; }
            set { m_StopEnabled = value; }
        }
    }
}
